package liuyuyang.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.beanutils.BeanUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

@Component
public class Jwt {
    @Resource
    private JwtConfig jwtConfig;

    // 创建 Token
    public String createToken(Object data) {
        try {
            // 获得jwt构建对象
            JwtBuilder jwtBuilder = Jwts.builder();

            // 设置数据
            if (data == null) throw new RuntimeException("数据不能为空");

            BeanInfo beanInfo = Introspector.getBeanInfo(data.getClass());

            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                // 获得属性名
                String name = propertyDescriptor.getName();

                // 获得属性值
                Object value = propertyDescriptor.getReadMethod().invoke(data);

                if (value != null) {
                    jwtBuilder.claim(name, value);
                }
            }

            // 设置过期时间
            jwtBuilder.setExpiration(DateTime.now().plusMinutes(jwtConfig.getExpire()).toDate());

            // 设置加密方式
            jwtBuilder.signWith(SignatureAlgorithm.RS256, jwtConfig.getPrivateKey());

            // 生成Token
            return jwtBuilder.compact();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    // 直接解析Token
    public Claims parserToken(String token) {
        Claims claims = null;

        try {
            claims = Jwts.parser().setSigningKey(jwtConfig.getPublicKey()).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return claims;
    }

    // 以JavaBean形式解析Token
    public <T> T resolverToken(String token, Class<T> beanClass) throws Exception {
        // 去除Bearer 前缀
        token = token.replace("Bearer ","");

        // 获得解析后内容
        Claims body = Jwts.parser().setSigningKey(jwtConfig.getPublicKey()).parseClaimsJws(token).getBody();

        // 将内容封装到对象JavaBean
        T bean = beanClass.newInstance();

        BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            // 获得属性名
            String name = propertyDescriptor.getName();

            // 通过属性名，获得对应解析的数据
            Object value = body.get(name);

            if (value != null) {
                // 将获得的数据封装到对应的JavaBean中
                BeanUtils.setProperty(bean, name, value);
            }
        }

        return bean;
    }
}
